<?php

namespace XWAM\Addon\PXCallSystem\Model;

/**
 * AgiManagerModel
 *
 * @since 1.0 <2015-5-13> SoChishun Added.
 */
class AgiManagerModel {

    /**
     * 返回queue show命令的解析结果
     * @param int $interval 缓存时长,默认3秒
     * @return string|array
     * @since 1.0 <2015-7-28> SoChishun Added.
     */
    public function cli_queue_show($interval = 3) {
        $cache_key = 'queue_show';
        if (S($cache_key)) {
            return S($cache_key);
        }
        $queue = '';
        $is_member = false;
        $is_callers = false;
        $acallstates = array('(Busy)' => '<img data-sort="1" src="' . C("TMPL_PARSE_STRING.__THEME__") . 'Images/InUse.png" alt="talk" />通话中B', '(In use)' => '<img data-sort="1" src="' . C("TMPL_PARSE_STRING.__THEME__") . 'Images/InUse.png" alt="talk" />通话中U', '(Ringing)' => '<img data-sort="2" src="' . C("TMPL_PARSE_STRING.__THEME__") . 'Images/Ringing.png" alt="ring" />振铃中');
        $aextenstates = array('(Invalid)' => '无效', '(paused)' => '<span style="color:#F00">示忙</span>', '(Not in use)' => '空闲', '(Unavailable)' => '<span style="color:#b3424a">不可用</span>');
        $astrategynames = array('ringall' => '呼叫所有', 'rrmemory' => '记忆呼叫', 'random' => '随机');
        $seatnames = M('tuser_member')->cache(15)->where(array('userType' => 'SEAT'))->getField('userName, personalName');
        $adminsites = M('tuser_member')->cache(15)->where(array('userType' => 'ADMIN'))->getField('siteID, userName');
        $queuesites = M('tcti_acd_queue')->cache(15)->where()->getField('extension, siteID');
        $lines = preg_split("/[\n]+/", trim(asmanager_query_result('queue show')));
        $aout = false;
        foreach ($lines as $line) {
            $line = trim($line);
            if ('No Members' == $line || 'No Callers' == $line) {
                $is_member = false;
                $is_callers = false;
                continue;
            }
            if (false !== strpos($line, 'Members')) {
                $is_member = true;
                $is_callers = false;
                continue;
            }
            if (false !== strpos($line, 'Callers')) {
                $is_member = false;
                $is_callers = true;
                continue;
            }
            if (strpos($line, 'strategy')) {
                $is_member = false;
                $is_callers = false;
                // 2990 has 0 calls (max unlimited) in 'random' strategy (0s holdtime, 0s talktime), W:0, C:0, A:0, SL:0.0% within 0s
                $queue = substr($line, 0, strpos($line, ' '));
                $strategy = '';
                $strategy_text = '';
                if (preg_match('/\'.*\'/', $line, $matches)) {
                    $strategy = trim($matches[0], '\'');
                    $strategy_text = $strategy && array_key_exists($strategy, $astrategynames) ? $astrategynames[$strategy] : $strategy;
                }
                $site_id = array_key_exists($queue, $queuesites) ? $queuesites[$queue] : 0;
                $site_id_text = $site_id . ($site_id && array_key_exists($site_id, $adminsites) ? (' (' . $adminsites[$site_id] . ')') : '');
                $aout[$queue] = array('strategy' => $strategy, 'strategy_text' => $strategy_text, 'site_id' => $site_id, 'site_id_text' => $site_id_text, 'members_sum' => array('total' => 0, 'idle' => 0, 'ringing' => 0, 'busy' => 0), 'callers_sum' => array('total' => 0), 'members' => array(), 'callers' => array());
            } else {
                if ($is_member) {
                    // Local/13950197906@ext-agent/n (Not in use) has taken no calls yet
                    // 360 (SIP/360) (dynamic) (Unavailable) has taken no calls yet
                    //  378 (SIP/378) (dynamic) (Not in use) has taken 57 calls (last was 422 secs ago)
                    $aline = explode(' ', $line, 2);
                    $exten = $aline[0];
                    $line = $aline[1];
                    $exten_full_name = $exten;
                    $bar = '';
                    if (!strpos($exten, '/')) {
                        if (array_key_exists($exten, $seatnames)) {
                            $exten_full_name = $seatnames[$exten];
                        }
                        // 示忙控制
                        $chked = (false === strpos($line, '(paused)')) ? '' : 'checked="checked"';
                        $bar = "<input type='checkbox' $chked data-extension='$exten' data-queue='$queue' title='勾选=示忙,不选=示闲' />示忙";

                        $aline = explode(' ', $line, 2);
                        $exten.=' ' . $aline[0];
                        $exten_full_name = $exten . " ($exten_full_name)";
                        $line = $aline[1];
                    }
                    $row = array('exten' => $exten, 'exten_full_name' => $exten_full_name, 'call_state' => '', 'call_state_text' => '-', 'exten_state' => '', 'exten_state_text' => '', 'calls_count' => 0, 'last_ago' => 0, 'input' => $bar);
                    foreach ($acallstates as $key => $value) {
                        if (false !== strpos($line, $key)) {
                            $row['call_state'] = $key;
                            $row['call_state_text'] = $value;
                            break;
                        }
                    }
                    foreach ($aextenstates as $key => $value) {
                        if (false !== strpos($line, $key)) {
                            $row['exten_state'] = $key;
                            $row['exten_state_text'] = $value;
                            break;
                        }
                    }
                    if (!strpos($line, 'taken no calls')) {
                        preg_match_all('/\d+/', $line, $matches);
                        $row['calls_count'] = $matches[0][0];
                        $row['last_ago'] = $matches[0][1];
                    }
                    $aout[$queue]['members'][] = $row;
                    $aout[$queue]['members_sum']['total'] ++;
                    if (strpos($row['call_state'], 'InUse') || strpos($row['call_state'], 'Busy')) {
                        $aout[$queue]['members_sum']['busy'] ++;
                    }
                    if (strpos($row['call_state'], 'Ringing')) {
                        $aout[$queue]['members_sum']['ringing'] ++;
                    }
                }
                if ($is_callers) {
                    // Local/2420@from-internal-00017d7b;2 (wait: 0:22, prio: 0)
                    $row = array('channel' => '', 'wait' => '');
                    $aline = explode(' ', $line, 3);
                    $row['channel'] = $aline[1];
                    $line = substr($aline[2], strpos($aline[2], ':') + 2);
                    $row['wait'] = substr($line, 0, strpos($line, ','));
                    $aout[$queue]['callers'][] = $row;
                    $aout[$queue]['callers_sum']['total'] ++;
                }
            }
        }
        ksort($aout);
        S($cache_key, $aout, $interval);
        //var_export($aout[4001]);
        return $aout;
    }

    /**
     * 返回sip show peers命令结果的格式化数组(获取分机注册服务器)
     * @param int $expire
     * @return array array('Name'=>'', 'Host'=>'', 'Dyn'=>'', 'Forcerport'=>'', 'ACL'=>'', 'Port'=>'', 'Status'=>'')
     * @since 1.0 2014-10-31 by sutroon
     * @since 2.0 2015-6-1 SoChishun 由get_command_sip_show_peers_data重构为cli_sip_show_peers.
     */
    public function cli_sip_show_peers($fy = false, $expire = 3) {
        $skey = 'sip_show_peers';
        $data = S($skey);
        if ($data) {
            return $data;
        }
        // 解析命令结果为数组
        $str = trim(asmanager_query_result('sip show peers'));
        $arr = preg_split("/[\n]+/", trim($str), -1, PREG_SPLIT_NO_EMPTY);
        unset($arr[0]); //  去掉表头
        $n = count($arr);
        $arrOut[] = $arr[$n]; // 取出统计
        unset($arr[$n]); // 去掉表底
        $arrfy = array('Unspecified' => '未知', 'Yes' => '是', 'No' => '否', 'UNKNOWN' => '未知', 'Unmonitored' => '无监视');
        $keys = array('Name', 'Host', 'Dyn', 'Forcerport', 'ACL', 'Port', 'Status');
        foreach ($arr as $row) {
            $row = preg_replace("/OK\s+\((\d+)\s+ms\)/", "OK($1ms)", trim($row));
            if ($fy) {
                foreach ($arrfy as $w => $cn) {
                    $row = str_replace($w, $cn, $row);
                }
            }
            $sub = preg_split("/[\s]+/", $row);
            switch (count($sub)) {
                case 7:
                    $sub = array_combine($keys, $sub);
                    break;
                case 5:
                    array_splice($sub, 2, 1, array('', $sub[2], ''));
                    $sub = array_combine($keys, $sub);
                    break;
                case 4:
                    array_splice($sub, 2, 0, array('', '', ''));
                    $sub = array_combine($keys, $sub);
                    break;
            }
            $arrOut[] = $sub;
        }
        S($skey, $arrOut, $expire);
        return $arrOut;
    }

    /**
     * 获取分机详情
     * @param array $extensions
     * @return array array($exten=>array('Reg'=>'','Useragent'=>''));
     * @since 2014-11-6 by sutroon
     * @since 2.0 <2015-6-1> SoChishun 由get_extension_details重构为cli_sip_show_peer
     */
    public function cli_sip_show_peer($extensions, $expire = 3) {
        $skey = 'sip_show_peer';
        $data = S($skey);
        if ($data) {
            return $data;
        }
        // 解析命令结果为数组        
        foreach ($extensions as $extension) {
            $cmds[$extension] = 'sip show peer ' . $extension;
        }
        $returns = asmanager_query_results($cmds);
        foreach ($returns as $k => $str) {
            $arr = preg_split("/[\n]+/", trim($str), -1, PREG_SPLIT_NO_EMPTY);
            $arrOut = array();
            foreach ($arr as $row) {
                $arrRow = explode(':', $row, 2);
                if (trim($arrRow[0]) == 'Useragent') {
                    $arrOut['Useragent'] = $arrRow[1];
                    continue;
                }
                if (trim($arrRow[0]) == 'Reg. Contact') {
                    $arrRow[1] = substr($arrRow[1], strpos($arrRow[1], '@') + 1);
                    $arrRow[1] = substr($arrRow[1], 0, strpos($arrRow[1], ':'));
                    $arrOut['Reg'] = $arrRow[1];
                    continue;
                }
            }
            $arr_return[$k] = $arrOut;
        }
        S($skey, $arr_return, $expire);
        return $arr_return;
    }

    /**
     * 获取分机状态图标
     * @return array array($name=>array('State' => '','Sort'=>0, 'Icon' => ''))
     * @since 1.0 2014-9-10 by sutroon
     * @since 2.0 2015-6-1 SoChishun 由get_sip_hints重构为cli_core_show_hints
     */
    public function cli_core_show_hints($expire = 3) {
        $skey = 'core_show_hints';
        $data = S($skey);
        if ($data) {
            return $data;
        }
        // 解析命令结果为数组
        $str = trim(asmanager_query_result('core show hints'));
        $values = preg_split("/[\n]+/", trim($str), -1, PREG_SPLIT_NO_EMPTY);
        $arr = false;
        foreach ($values as $val) {
            $sip_name = explode("@", $val);
            $name = trim($sip_name[0]);
            if ('*' == $name[0] || 'e' != $sip_name[1][0]) {
                continue;
            }
            $sip_state = array('State' => '', 'Sort' => '', 'Icon' => '');
            if (preg_match('/State:Unavailable/', $val)) {
                $sip_state = array('State' => '', 'Sort' => 4, 'Icon' => "<img data-sort='4' src='" . C('TMPL_PARSE_STRING.__THEME__') . "Images/Unavailable.png'width='11' height='10' alt='offline' />" . "离 线");
            } else if (preg_match('/State:Idle/', $val)) {
                $sip_state = array('State' => '', 'Sort' => 3, 'Icon' => "<img data-sort='3' src='" . C('TMPL_PARSE_STRING.__THEME__') . "Images/Idle.png' alt='free' />" . "空 闲");
            } else if (preg_match('/State:Busy/', $val) || preg_match('/State:InUse/', $val)) {
                $sip_state = array('State' => '', 'Sort' => 1, 'Icon' => "<img data-sort='1' src='" . C('TMPL_PARSE_STRING.__THEME__') . "Images/InUse.png' width='17' height='17' alt='talk' />" . "通 话");
            } else if (preg_match('/State:Ringin/', $val)) {
                $sip_state = array('State' => '', 'Sort' => 2, 'Icon' => "<img data-sort='2' src='" . C('TMPL_PARSE_STRING.__THEME__') . "Images/Ringing.png' alt='ring' />" . "振 铃");
            }
            $arr[$name] = $sip_state;
        }
        S($skey, $arr, $expire);
        return $arr;
    }

    /**
     * 返回core_show_channels_concise命令结果数组
     * 返回通道信息(包含中继和分机)
     * @return array array('Channel'=>'', 'Context'=>'', 'Extension'=>'', 'Prio'=>'', 'State'=>'', 'Application'=>'', 'Data'=>'', 'CallerID'=>'', 'Accountcode'=>'', 'PeerAccount'=>'', 'What1'=>'', 'Duration'=>'', 'BridgedTo'=>'', 'Accountcode2'=>'')
     * @since 1.0 <2015-5-12> SoChishun Added.
     */
    public function cli_core_show_channels_concise($expire = 3) {
        $debug = I('debug');
        $skey = 'core_show_channels_concise';
        $data = S($skey);
        if ($data && !$debug) {
            return $data;
        }
        // 解析命令结果为数组
        $str = trim(asmanager_query_result('core show channels concise'));
        $keys = array('Channel', 'Context', 'Extension', 'Prio', 'State', 'Application', 'Data', 'CallerID', 'Accountcode', 'PeerAccount', 'What1', 'Duration', 'BridgedTo', 'Accountcode2'); // UserCaller 主叫, UserCalled 被叫
        $arr_rows = explode(PHP_EOL, $str);
        foreach ($arr_rows as $row) {
            $table[] = array_combine($keys, explode('!', $row));
        }
        $table2 = $this->cli_core_show_channels_concise_set_biz_data($table);
        if ($debug) {
            echo '<pre>', $str, '</pre>';
            //echo '<pre>' . trim(asmanager_query_result('core show channels verbose')) . '</pre>';
            echo '<table border="1">';
            echo '<tr><th>', implode('</th><th>', array_keys($table[0])), '</th></tr>';
            foreach ($table as $row) {
                echo '<tr><td>', implode('</td><td>', array_values($row)), '</td></tr>';
            }
            echo '</table>';
            echo '<hr /><table border="1">';
            echo '<tr><th>', implode('</th><th>', array_keys($table2[0])), '</th></tr>';
            foreach ($table2 as $row) {
                echo '<tr><td>', implode('</td><td>', array_values($row)), '</td></tr>';
            }
            echo '</table>';
        }
        S($skey, $table2, $expire);
        return $table2;
    }

    /**
     * 解析并填充业务数据
     * 新增UserTrunk(中继), UserCaller(主叫), UserCalled(被叫), UserExten(分机号)
     * @param array $row
     * @since 1.0 <2015-5-14> SoChishun Added.
     */
    function cli_core_show_channels_concise_set_biz_data($table) {
        // 查询数据库结果集
        $trunks = M('tcti_trunk')->cache(true)->getField('account', true); // 所有中继名称
        $strageties = M('tcti_task_strategy')->cache(true)->getField("id, callerNo", true); // 策略编号和主叫号码
        $extens_ecs = M('tuser_member')->where("userType='SEAT'")->cache(true)->getField("extensionNumber, ctiCallerNo, siteID", true); // 分机号和显示号码
        // 业务解析命令结果
        foreach ($table as $row) {
            $context = $row['Context'];
            if ('autocall-ivr' != $context && 'my-internal' != $context && 'xcall' != $context) {
                continue; // 不是主要通道, 忽略
            }
            $channel = $row['Channel'];
            $state = $row['State'];
            $extension = $row['Extension'];
            $application = $row['Application'];
            $data = $row['Data'];
            $accountcode = $row['Accountcode'];
            $bridgedto = $row['BridgedTo'];
            $row['UserTrunk'] = ''; // 中继名称
            $row['UserExten'] = ''; // 分机号
            $row['UserCaller'] = ''; // 主叫号码
            $row['UserCalled'] = ''; // 被叫号码
            $row['UserState'] = $state; // 通道状态
            $row['UserSiteID'] = ''; // 租户编号
            $row['UserDuration'] = sofn_seconds_format($row['Duration']);
            $row['Debug'] = '';
            //====0. 共用状态====
            //==0.1 外呼-呼叫=客户端接口外呼-呼叫
            //主通道：Context=my-internal, State=Down, Application=AppDial, Data=(Outgoing Line)
            //副通道：通过主通道Accountcode匹配
            //主叫：通过副通道CallerID，查询分机表“显示号码”字段
            //被叫：主通道CallerID            
            if ('my-internal' == $context && 'Down' == $state && 'AppDial' == $application && '(Outgoing Line)' == $data) {
                $row['Debug'] = '0.1 外呼-呼叫=客户端接口外呼-呼叫';
                foreach ($table as $row2) {
                    // 副通道
                    if ($accountcode == $row2['Accountcode'] && $channel != $row2['Channel']) {
                        $callerid2 = $row2['CallerID'];
                        $row['UserExten'] = $callerid2; // 分机号
                        $row['UserCaller'] = $extens_ecs && array_key_exists($callerid2, $extens_ecs) ? $extens_ecs[$callerid2]['ctiCallerNo'] : $callerid2; // 主叫
                        break;
                    }
                }
                $row['UserCalled'] = $row['CallerID']; // 被叫
                $row['UserTrunk'] = substr($channel, 4, strpos($channel, '-') - 4); // 中继名称 Trunk SIP/user1-00000023
                $table2[] = $row;
                continue;
            }
            //==0.2 分机外呼-振铃, 客户端接口外呼-振铃
            //主通道：Context=my-internal, State=Ringing, Application=AppDial, Data=(Outgoing Line)
            //副通道：通过主通道Accountcode匹配
            //主叫：通过副通道CallerID查询分机表
            //被叫：主通道CallerID
            if ('my-internal' == $context && 'Ringing' == $state && 'AppDial' == $application && '(Outgoing Line)' == $data) {
                $row['Debug'] = '0.2 分机外呼-振铃, 客户端接口外呼-振铃';
                foreach ($table as $row2) {
                    // 副通道
                    if ($accountcode == $row2['Accountcode'] && $channel != $row2['Channel']) {
                        $callerid2 = $row2['CallerID'];
                        $row['UserExten'] = $callerid2; // 分机号
                        $row['UserCaller'] = $extens_ecs && array_key_exists($callerid2, $extens_ecs) ? $extens_ecs[$callerid2]['ctiCallerNo'] : $callerid2; // 主叫
                        break;
                    }
                }
                $row['UserCalled'] = $row['CallerID']; // 被叫
                $row['UserTrunk'] = substr($channel, 4, strpos($channel, '-') - 4); // 中继名称
                $table2[] = $row;
                continue;
            }
            // ====1. 分机外呼 Begin====
            //==1.2 分机外呼--通话
            //主通道：Context=my-internal, State=Up, Application=AppDial, Data=(Outgoing Line)
            //副通道：通过主通道BridgedTo匹配
            //主叫：通过副通道CallerID，查询分机表“显示号码”字段
            //被叫：主通道CallerID
            if ('my-internal' == $context && 'Up' == $state && 'AppDial' == $application && '(Outgoing Line)' == $data && 'S'==$bridgedto[0]) {
                $row['Debug'] = '1.2 分机外呼--通话';
                foreach ($table as $row2) {
                    // 副通道
                    if ($bridgedto == $row2['Channel']) {
                        $callerid2 = $row2['CallerID'];

                        if ($extens_ecs && array_key_exists($callerid2, $extens_ecs)) {
                            // 分机号是真实分机号
                            $row['UserExten'] = $callerid2; // 分机号
                        } else {
                            // 分机号是分机显示号码,这时候需要解析bridgeto
                            $row['UserExten'] = substr($bridgedto, 4, strpos($bridgedto, '-') - 4);
                        }
                        // 策略外呼-应答后外呼模式[2015-8-6]
                        if ('L' == $bridgedto[0]) {
                            $row['UserExten'] = substr($bridgedto, 6, strpos($bridgedto, '@') - 6);
                        }
                        $row['UserCaller'] = $extens_ecs && array_key_exists($callerid2, $extens_ecs) ? $extens_ecs[$callerid2]['ctiCallerNo'] : $callerid2; // 主叫                        
                    }
                }
                $row['UserCalled'] = $row['CallerID']; // 被叫
                $row['UserTrunk'] = substr($channel, 4, strpos($channel, '-') - 4); // 中继名称
                $table2[] = $row;
                continue;
            }
            // ====1. 分机外呼 End====
            // ====2. 策略外呼 Begin====
            //==2.0 策略外呼-发起呼叫
            //主通道：Context=my-internal, State=Down, Application=(None)
            //副通道：无
            //主叫：通过Accountcode策略编号查找策略表“显示号码”字段
            //被叫：无法获知
            if ('my-internal' == $context && 'Down' == $state && '(None)' == $application) {
                $row['Debug'] = '2.0 策略外呼-发起呼叫';
                $task_strategy_id = substr($accountcode, 0, strpos($accountcode, '.'));
                $row['UserCaller'] = $task_strategy_id && array_key_exists($task_strategy_id, $strageties) ? $strageties[$task_strategy_id] : '策略未知';
                //$row['UserCalled'] = $row['Extension'];                
                $called = substr($accountcode, 0, strpos($accountcode, '.OUT.'));
                $row['UserCalled'] = substr($called, strrpos($called, '.') + 1);
                $row['UserTrunk'] = substr($channel, 4, strpos($channel, '-') - 4); // 中继名称
                $table2[] = $row;
                continue;
            }
            // ==2.1 策略外呼--客户振铃
            //主通道：Context=my-internal, State=Ringing，Application=(None)
            //副通道：无
            //主叫：通过Accountcode策略编号查找策略表“显示号码”字段
            //被叫：解析accountcode
            if ('my-internal' == $context && 'Ringing' == $state && '(None)' == $application) {
                $row['Debug'] = '2.1 策略外呼--客户振铃';
                $task_strategy_id = substr($accountcode, 0, strpos($accountcode, '.'));
                $row['UserCaller'] = $task_strategy_id && array_key_exists($task_strategy_id, $strageties) ? $strageties[$task_strategy_id] : '策略未知';
                $called = substr($accountcode, 0, strpos($accountcode, '.OUT.'));
                $row['UserCalled'] = substr($called, strrpos($called, '.') + 1);
                $row['UserTrunk'] = substr($channel, 4, strpos($channel, '-') - 4); // 中继名称
                $table2[] = $row;
                continue;
            }
            // ==2.2 策略外呼--应答(客户摘机后,分机振铃)
            //主通道：Context=autocall-ivr,  BridgedTo前缀为Local
            //副通道：通过主通道BridgedTo匹配
            //主叫：通过Accountcode策略编号查找策略表“显示号码”字段
            //被叫：主通道CallerID
            if ('autocall-ivr' == $context && $bridgedto && 'L' == $bridgedto[0]) {
                $row['Debug'] = '2.2 策略外呼--应答(客户摘机后,分机振铃)';
                foreach ($table as $row2) {
                    // 副通道
                    if ($bridgedto == $row2['Channel']) {
                        $callerid2 = $row2['CallerID'];
                        $row['UserExten'] = $callerid2; // 分机号
                    }
                }
                $task_strategy_id = substr($accountcode, 0, strpos($accountcode, '.'));
                $row['UserCaller'] = $task_strategy_id && array_key_exists($task_strategy_id, $strageties) ? $strageties[$task_strategy_id] : '策略未知';
                $row['UserCalled'] = $row['CallerID']; // 被叫
                $row['UserTrunk'] = substr($channel, 4, strpos($channel, '-') - 4); // 中继名称
                $row['UserState'] = 'Answer';
                $table2[] = $row;
                continue;
            }
            // ==2.3 策略外呼--通话
            //主通道：Context=autocall-ivr, BridgedTo前缀为SIP
            //副通道：通过主通道BridgedTo匹配 
            //主叫：通过Accountcode策略编号查找策略表“显示号码”字段
            //被叫：主通道CallerID
            if ('autocall-ivr' == $context && $bridgedto && 'S' == $bridgedto[0]) {
                $row['Debug'] = '2.3 策略外呼--通话';
                foreach ($table as $row2) {
                    // 副通道
                    if ($bridgedto == $row2['Channel']) {
                        $callerid2 = $row2['CallerID'];
                        $row['UserExten'] = $callerid2; // 分机号
                    }
                }
                $task_strategy_id = substr($accountcode, 0, strpos($accountcode, '.'));
                $row['UserCaller'] = $task_strategy_id && array_key_exists($task_strategy_id, $strageties) ? $strageties[$task_strategy_id] : '策略未知';
                $row['UserCalled'] = $row['CallerID']; // 被叫
                $row['UserTrunk'] = substr($channel, 4, strpos($channel, '-') - 4); // 中继名称
                $table2[] = $row;
                continue;
            }
            //2.3.1按码转队列，等待按码（策略外呼-应答）
            //主通道：Context=autocall-ivr，BridgedTo=(None)，
            //副通道：无
            //主叫：Channel中的3805320
            //被叫：分机号
            if ('autocall-ivr' == $context && '(None)' == $bridgedto && 'S' == $channel[0]) {
                $row['Debug'] = '2.3.1按码转队列，等待按码（策略外呼-应答）';
                $task_strategy_id = substr($accountcode, 0, strpos($accountcode, '.'));
                $row['UserCaller'] = $task_strategy_id && array_key_exists($task_strategy_id, $strageties) ? $strageties[$task_strategy_id] : '策略未知';
                $row['UserCalled'] = $row['Extension']; // 被叫
                $row['UserTrunk'] = substr($channel, 4, strpos($channel, '-') - 4); // 中继名称
                $row['UserState'] = 'Answer';
                $table2[] = $row;
                continue;
            }
            // ====2. 策略外呼 End====
            // ====3. 分机互打 Begin====
            //==3.0 分机互打-呼叫
            //主通道：Context=xcall, State=Ring, Application=AGI
            //副通道：无
            //主叫：主通道CallerID
            //被叫：无
            if ('xcall' == $context && 'Ring' == $state && 'AGI' == $application) {
                $row['Debug'] = '3.0 分机互打-呼叫';
                $row['UserExten'] = $row['CallerID']; // 分机号
                $row['UserCaller'] = $row['CallerID']; // 主叫
                $row['UserCalled'] = ''; // 被叫
                $row['UserTrunk'] = ''; // 中继名称
                $row['UserState'] = 'Down';
                $table2[] = $row;
                continue;
            }
            //==3.1 分机互打-振铃
            //主通道：Context=xcall, State=Ringing, Application=AppDial, Data=(Outgoing Line), Channel=SIP开头
            //副通道：通过主通道Accountcode匹配
            //主叫：副通道CallerID
            //被叫：主通道CallerID
            if ('xcall' == $context && 'Ringing' == $state && 'AppDial' == $application && '(Outgoing Line)' == $data && 'S' == $channel[0]) {
                $row['Debug'] = '3.1 分机互打-振铃';
                foreach ($table as $row2) {
                    // 副通道
                    if ($accountcode == $row2['Accountcode'] && $channel != $row2['Channel']) {
                        $callerid2 = $row2['CallerID'];
                        $row['UserExten'] = $callerid2; // 分机号
                        $row['UserCaller'] = $callerid2; // 主叫
                        break;
                    }
                }
                $row['UserCalled'] = $row['CallerID']; // 被叫
                $row['UserTrunk'] = ''; // 中继名称
                $table2[] = $row;
                continue;
            }
            //==3.2 分机互打-通话
            //主通道：Context=xcall, Channel=SIP开头, BridgedTo=SIP开头
            //副通道：通过主通道BridgedTo匹配
            //主叫：副通道CallerID
            //被叫：主通道CallerID
            if ('xcall' == $context && 'S' == $channel[0] && $bridgedto && 'S' == $bridgedto[0]) {
                $row['Debug'] = '3.2 分机互打-通话';
                $callerid_is_exten = array_key_exists($row['CallerID'], $extens_ecs);
                foreach ($table as $row2) {
                    // 副通道
                    if ($bridgedto == $row2['Channel']) {
                        $callerid2 = $row2['CallerID'];
                        if ($callerid_is_exten) {
                            // ##转队列 2015-8-7
                            $row['UserExten'] = $row['CallerID'];
                            $row['UserCaller'] = $row['CallerID']; // 主叫
                            $row['UserCalled'] = $callerid2; // 被叫
                            $row['UserTrunk'] = substr($bridgedto, 4, strpos($bridgedto, '-') - 4); // 中继名称
                        } else {
                            // ##转分机
                            $row['UserExten'] = $callerid2; // 分机号
                            $row['UserCaller'] = $callerid2; // 主叫
                            $row['UserCalled'] = $row['CallerID']; // 被叫
                            $row['UserTrunk'] = ''; // 中继名称
                        }
                        break;
                    }
                }
                $table2[] = $row;
                continue;
            }
            // ====3. 分机互打 End====
            // ====4. 来话导航(呼入) Being====
            //==4.1 来话导航-振铃
            //主通道：Context=my-internal, BridgedTo以Local开头，Data=Local开头
            //副通道：通过主通道BridgedTo匹配
            //主叫：主通道CallerID
            //被叫：通过副通道CallerID，查询分机表“显示号码”字段
            if ('my-internal' == $context && $bridgedto && 'L' == $bridgedto[0] && $data && 'L' == $data[0]) {
                $row['Debug'] = '4.1 来话导航-振铃';
                foreach ($table as $row2) {
                    // 副通道
                    if ($bridgedto == $row2['Channel']) {
                        $callerid2 = $row2['CallerID'];
                        $row['UserExten'] = $callerid2; // 分机号
                        $row['UserCalled'] = $extens_ecs && array_key_exists($callerid2, $extens_ecs) ? $extens_ecs[$callerid2]['ctiCallerNo'] : $callerid2; // 被叫
                    }
                }
                $row['UserCaller'] = $row['CallerID']; // 主叫
                $row['UserTrunk'] = substr($channel, 4, strpos($channel, '-') - 4); // 中继名称
                $row['UserState'] = 'Ringing';
                $table2[] = $row;
                continue;
            }
            //==4.2 来话导航-通话
            //主通道：Context=my-internal, BridgedTo以SIP开头，Data=Local开头
            //副通道：通过主通道BridgedTo匹配
            //主叫：主通道CallerID
            //被叫：通过副通道CallerID，查询分机表“显示号码”字段(2015-8-24 取消显示号码,直接显示分机号)
            if ('my-internal' == $context && $bridgedto && 'S' == $bridgedto[0] && $data && 'L' == $data[0]) {
                $row['Debug'] = '4.2 来话导航-通话';
                foreach ($table as $row2) {
                    // 副通道
                    if ($bridgedto == $row2['Channel']) {
                        $callerid2 = $row2['CallerID'];
                        $row['UserExten'] = $callerid2; // 分机号
                        $row['UserCalled'] = $callerid2; // 被叫
                        //$row['UserCalled'] = $extens_ecs && array_key_exists($callerid2, $extens_ecs) ? $extens_ecs[$callerid2]['ctiCallerNo'] : $callerid2; // 被叫
                    }
                }
                $row['UserCaller'] = $row['CallerID']; // 主叫
                $row['UserTrunk'] = substr($channel, 4, strpos($channel, '-') - 4); // 中继名称
                $table2[] = $row;
                continue;
            }
            //4.3 来话导航，##转分机-通话
            //主通道：Context=macro-dial-one, BridgedTo以SIP开头, Data=(Outgoing Line)
            //副通道：通过主通道BridgedTo匹配
            //主叫：副通道CallerID
            //被叫：主通道CallerID(分机号)
            if ('macro-dial-one' == $context && $bridgedto && 'S' == $bridgedto[0] && $data && '(Outgoing Line)' == $data) {
                $row['Debug'] = '4.3 来话导航-##转分机-通话';
                foreach ($table as $row2) {
                    // 副通道
                    if ($bridgedto == $row2['Channel']) {
                        $callerid2 = $row2['CallerID'];
                        $row['UserCaller'] = $callerid2; // 主叫
                    }
                }
                $row['UserExten'] = $row['CallerID']; // 分机号
                $row['UserCalled'] = $row['CallerID']; // 被叫
                $row['UserTrunk'] = substr($bridgedto, 4, strpos($bridgedto, '-') - 4); // 中继名称
                $table2[] = $row;
                continue;
            }
            // ====4. 来话导航(呼入) End====
            // ====5. 客户端接口外呼 Begin====
            //==5.2 客户端外呼-通话
            //主通道：Context=my-internal，BridgedTo=Local开头，Data=(Outgoing Line)
            //副通道：通过主通道BridgedTo匹配
            //主叫：通过副通道CallerID查询分机表
            //被叫：主通道CallerID
            if ('my-internal' == $context && $bridgedto && 'L' == $bridgedto[0] && '(Outgoing Line)' == $data) {
                $row['Debug'] = '5.2 客户端外呼-通话';
                foreach ($table as $row2) {
                    // 副通道
                    if ($bridgedto == $row2['Channel']) {
                        $callerid2 = $row2['CallerID'];
                        $row['UserExten'] = $callerid2; // 分机号
                        $row['UserCaller'] = $extens_ecs && array_key_exists($callerid2, $extens_ecs) ? $extens_ecs[$callerid2]['ctiCallerNo'] : $callerid2; // 主叫
                    }
                }
                $row['UserCalled'] = $row['CallerID']; // 被叫
                $row['UserTrunk'] = substr($channel, 4, strpos($channel, '-') - 4); // 中继名称
                $table2[] = $row;
                continue;
            }
            // ====5. 客户端接口外呼 End====
        }
        return $table2;
    }
}
